package com.yami.shop.common.util;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yami.shop.common.exception.YamiShopBindException;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Base64;

/**
 * 图片处理工具类
 * @author yami
 */
@Component
public class ImageUtil {

    /**
     * 将图片转为二进制数组
     * @param imgUrl
     * @return
     */
    public static byte[] imgToBinary(String imgUrl) {
        try {
            BufferedImage bufferedImage = ImageIO.read(new URL(imgUrl));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            String suffix = imgUrlFileType(imgUrl);
            //ImageIO无法写入jpeg文件 报Invalid argument to native writeImage，需重画
            if(StrUtil.equals(suffix, "jpg") || StrUtil.equals(suffix, "jpeg")){
                BufferedImage tag;
                tag = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_BGR);
                Graphics g = tag.getGraphics();
                g.drawImage(bufferedImage, 0, 0, null);
                g.dispose();
                bufferedImage = tag;
            }
            ImageIO.write(bufferedImage, suffix, baos);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (IOException e) {
            // 图片丢失，请重新上传图片
            throw new YamiShopBindException("yami.img.lose");
        }
    }

    /**
     * @param imgUrl
     * @return 文件得后缀，文件类型 jpg ,  png , ...
     */
    public static String imgUrlFileType(String imgUrl) {
        if (StrUtil.isBlank(imgUrl)) {
            return imgUrl;
        }
        imgUrl.trim();
        String[] split = imgUrl.split("\\.");
        String s = split[split.length - 1];
        return s;
    }

    /**
     * @param imgUrl
     * @return 获取文件名称
     */
    public static String imgUrlFileName(String imgUrl) {
        if (StrUtil.isBlank(imgUrl)) {
            return imgUrl;
        }
        imgUrl.trim();
        String[] split = imgUrl.split("/");
        String s = split[split.length - 1];
        return s;
    }
    /**
     * @param imgUrl
     * @return 获取文件名称 45d3631e97d8438d80f9db1369595b8c
     */
    public static String imgUrlFileNameNoSuffix(String imgUrl) {
        if (StrUtil.isBlank(imgUrl)) {
            return imgUrl;
        }
        imgUrl.trim();
        String[] split = imgUrl.split("/");
        String s = split[split.length - 1];
        String[] split1 = s.split("\\.");
        return split1[0];
    }
    /**
     * 将图片进行格式转换
     * @param resType 目标文件类型
     * @param resQuality 目标文件的质量
     * @param image 图片源
     * @return
     * @throws IOException
     */
    public static byte[] converterType(String resType,float resQuality,BufferedImage image) throws IOException {
        // 创建新的BufferedImage对象，并将原始PNG图像复制到新的BufferedImage对象中
        BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
        newImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);

        // 创建JPEG压缩器，并设置压缩参数和质量
        ImageWriter writer = ImageIO.getImageWritersByFormatName(resType).next();
        ImageWriteParam param = writer.getDefaultWriteParam();
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(resQuality);

        // 将新的BufferedImage对象编码为JPEG格式
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        writer.setOutput(ImageIO.createImageOutputStream(baos));
        writer.write(null, new IIOImage(newImage, null, null), param);
        return baos.toByteArray();
    }

    /**
     * 转换为base64
     * @param data
     * @return
     */
    public static String toBase64(byte[] data){
        // 将压缩后的JPEG图像数据转换为base64格式的字符串，并将其输出到控制台
        return Base64.getEncoder().encodeToString(data);
    }

    /**
     * 根据坐标图片添加文字
     * @return 生成图片存储地址
     */
    public static MultipartFile writeImage(String srcImgPath,String text,int x,int y,String colorData){
        ByteArrayOutputStream qrOutputStream = null;
        String targetImgPath = "";
        try {

            BufferedImage bufferedImage = ImageIO.read(new URL(srcImgPath));
            //添加文字:
            BufferedImage bufImg = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(bufferedImage, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), null);


            //根据图片的背景设置水印颜色
            if(ObjectUtil.isEmpty(colorData)){
                g.setColor(new Color(0,0,0));
            }else {
                // 获取字体颜色
                int[] rgbs = hexToRgb(colorData);
                g.setColor(new Color(rgbs[0],rgbs[1],rgbs[2]));
            }
            //设置字体
            g.setFont(new Font("microsoft yahei", Font.PLAIN, 52));

            String prompt = StrUtil.maxLength(text, 1000);
            FontMetrics metrics = g.getFontMetrics(new Font("microsoft yahei", Font.PLAIN, 52));
            int length = metrics.stringWidth(prompt);
            int height = metrics.getAscent() - metrics.getLeading() - metrics.getDescent();
            int row = 1;
            int top = (60 - height) / 2;
            int paddingTop = y;
            int firstRowWidth = 450 - 20;
            if (length > firstRowWidth) {
                int rowLen = 0;
                int lastIndex = 0;
                for (int i = 0; i < prompt.length(); i++) {
                    rowLen += metrics.charWidth(prompt.charAt(i));
                    int fontMarginHeight = row == 1 ? height + top : 60 + top;
                    int rowWidth = row == 1 ? firstRowWidth : 450;
                    int leftWidth = row == 1 ?  20 + x : x;
                    if (rowLen >= rowWidth - 15) {
                        if (row == 5) {
                            String lastRowTxt = i == prompt.length() - 1 ?
                                    prompt.substring(lastIndex, i + 1) : prompt.substring(lastIndex, i) + "...";
                            g.drawString(lastRowTxt, leftWidth, paddingTop += fontMarginHeight);
                            break;
                        }
                        rowLen = 0;
                        g.drawString(prompt.substring(lastIndex, i + 1), leftWidth, paddingTop += fontMarginHeight);
                        row++;
                        lastIndex = i + 1;
                    }
                    if (i == prompt.length() - 1) {
                        g.drawString(prompt.substring(lastIndex), leftWidth, paddingTop += fontMarginHeight);
                    }
                }
            } else {
                int leftWidth = row == 1 ?  20 + x : x;
                g.drawString(prompt, leftWidth, paddingTop += top + height);
            }

            //画出水印

            g.dispose();

            //保存文件
            qrOutputStream = new ByteArrayOutputStream();
            //读文件
            try {
                ImageIO.write(bufImg, "jpg", qrOutputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return new OssMultipartFile("111.jpg", ".jpg", qrOutputStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
            throw new YamiShopBindException("生成图片异常!");
        }finally {
            try {
                if (null != qrOutputStream){
                    qrOutputStream.flush();
                    qrOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static int[] hexToRgb(String hex) {
        int r = Integer.parseInt(hex.substring(1, 3), 16);
        int g = Integer.parseInt(hex.substring(3, 5), 16);
        int b = Integer.parseInt(hex.substring(5, 7), 16);
        return new int[]{r, g, b};
    }

}
